package com.cskaoyan.service.promotion;

import com.cskaoyan.bean.Cart;
import com.cskaoyan.bean.promotion.Coupon;
import com.cskaoyan.bean.promotion.CouponExample;
import com.cskaoyan.bean.promotion.CouponUser;
import com.cskaoyan.bean.promotion.CouponUserExample;
import com.cskaoyan.bo.promotion.CouponUpdateBo;
import com.cskaoyan.bo.promotion.WxCouponReceiveBo;
import com.cskaoyan.mapper.CartMapper;
import com.cskaoyan.mapper.CouponMapper;
import com.cskaoyan.mapper.CouponUserMapper;
import com.cskaoyan.utils.Converter;
import com.cskaoyan.utils.DataUtils;
import com.cskaoyan.utils.PojoUtils;
import com.cskaoyan.vo.promotion.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sound.midi.Soundbank;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @autyor:caicaicai
 */
@Service
public class CouponServiceImpl implements CouponService {

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    CouponUserMapper couponUserMapper;

    @Autowired
    CartMapper cartMapper;

    @Override
    public CouponListVo query(Integer page, Integer limit, String sort, String order,
                              String name, Short type, Short status) {
        PageHelper.startPage(page, limit);
        CouponExample couponExample = new CouponExample();
        couponExample.setOrderByClause(sort + " " + order);
        //条件查询
        CouponExample.Criteria criteria = couponExample.createCriteria();//sql语句的拼接${}
        criteria.andDeletedEqualTo(false);//逻辑删除为false
        if(name != null && !"".equals(name)){
            criteria.andNameLike("%" + name + "%");
        }
        if(type != null && !"".equals(type)){
            criteria.andTypeEqualTo(type);
        }
        if(status != null && !"".equals(status)){
            criteria.andStatusEqualTo(status);
        }
        //where name like "%name%" and type = "xxx" and status = "xxx"
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);

        PageInfo<Coupon> couponPageInfo = new PageInfo<>(coupons);
        long total = couponPageInfo.getTotal();

        CouponListVo couponListVo = new CouponListVo();
        couponListVo.setItems(coupons);
        couponListVo.setTotal(total);
        return couponListVo;
    }

    @Override
    public int update(Coupon coupon) {
        int affectedRows = couponMapper.updateByPrimaryKeySelective(coupon);
        if(affectedRows == 1){
            return 200;
        }
        return 404;
    }

    @Override
    public int delete(Coupon coupon) {
        //逻辑删除，即修改属性deleted=true
        coupon.setDeleted(true);
        int affectedRows =couponMapper.updateByPrimaryKeySelective(coupon);
        if(affectedRows == 1){
            return 200;
        }
        return 404;
    }

    @Override
    public Coupon read(Integer id) {
        Coupon coupon = couponMapper.selectByPrimaryKey(id);
        return coupon;
    }

    @Override
    public CouponListuserVo listuser(Integer page, Integer limit, Integer couponId, String sort, String order, Integer userId, Short status) {
        PageHelper.startPage(page, limit);
        CouponUserExample couponUserExample = new CouponUserExample();
        //构造条件
        couponUserExample.setOrderByClause(sort + " " + order);
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        criteria.andDeletedEqualTo(false);//查询逻辑删除deleted=false
        criteria.andCouponIdEqualTo(couponId);
        if(userId != null && !"".equals(userId)){
            criteria.andUserIdEqualTo(userId);
        }
        if(status != null && !"".equals(status)){
            criteria.andStatusEqualTo(status);
        }

        List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);

        PageInfo<CouponUser> couponUserPageInfo = new PageInfo<>(couponUsers);
        long total = couponUserPageInfo.getTotal();

        CouponListuserVo couponListuserVo = new CouponListuserVo();
        couponListuserVo.setItems(couponUsers);
        couponListuserVo.setTotal(total);
        return couponListuserVo;
    }

    @Override
    public Coupon create(Coupon coupon) {
        Date nowDate = DataUtils.getCurrentTime();
        coupon.setAddTime(nowDate);
        coupon.setUpdateTime(nowDate);

        //插入数据后，主键被塞回输入映射的对象中
        couponMapper.insertSelective(coupon);
        return coupon;
    }

    @Override
    public WxCouponListVo queryWx(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();//sql语句的拼接${}
        criteria.andDeletedEqualTo(false);//逻辑删除为false
        WxCouponListCouponVo wxCouponListCouponVo = new WxCouponListCouponVo();
        List<WxCouponListCouponVo> couponVos = couponMapper.selectWxCouponListCouponVoByExample(couponExample);

        PageInfo<WxCouponListCouponVo> couponPageInfo = new PageInfo<>(couponVos);
        long total = couponPageInfo.getTotal();

        WxCouponListVo wxCouponListVo = new WxCouponListVo();
        wxCouponListVo.setData(couponVos);
        wxCouponListVo.setCount(total);
        return wxCouponListVo;
    }

    /**
     * 1）根据status + userId + deleted=false 查coupon_user表得到所有coupon_id
     * 2）根据所有coupon_id（即id) 分页查询  coupon表得到List<8个属性>
     * @param page
     * @param size
     * @param status
     * @return
     */
    @Override
    public WxCouponMylistVo queryMylistWx(Integer userId, Integer page, Integer size, Short status) {
        //1)根据status + userId + deleted=false 查coupon_user表得到所有coupon_id
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        criteria.andDeletedEqualTo(false).andUserIdEqualTo(userId).andStatusEqualTo(status);
        List<Integer> couponIds = couponUserMapper.selectCouponIdsByExample(couponUserExample);
       //集合couponIds 是否需要判空?
        if(couponIds.size() == 0){
            return  null;
        }

        //2）根据所有coupon_id（即id) 分页查询 coupon表得到List<8个属性>
        PageHelper.startPage(page, size);
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteriaCoupon = couponExample.createCriteria();
        criteriaCoupon.andIdIn(couponIds);
        List<WxCouponMylistCouponVo> couponVos = couponMapper.selectWxCouponMylistCouponVoByExample(couponExample);

        PageInfo<WxCouponMylistCouponVo> couponVoPageInfo = new PageInfo<>(couponVos);
        long total = couponVoPageInfo.getTotal();

        WxCouponMylistVo wxCouponMylistVo = new WxCouponMylistVo();
        wxCouponMylistVo.setData(couponVos);
        wxCouponMylistVo.setCount(total);
        return wxCouponMylistVo;
    }

    @Override
    public List<WxCouponMylistCouponVo> selectListWx(Integer userId, Integer cartId, Integer grouponRulesId) {
        //1）条件userId  + status=0 + deleted=false  查询coupon_user表得List<coupon_id>
        //查询该用户该状态(可用)的所有优惠券
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        criteria.andUserIdEqualTo(userId).andStatusEqualTo((short)0).andDeletedEqualTo(false);

        List<Integer> couponIds = couponUserMapper.selectCouponIdsByExample(couponUserExample);
        //集合couponIds 是否需要判空?
        if(couponIds.size() == 0){
            return  null;
        }

        //3）条件coupon_id + min>price + status=0 + 商品限制（？不知道怎么写） + deleted=false 查询coupon表得 List<8个属性>
        //（很多种优惠券）分别查询每一种优惠券这种情况下是否可用？
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria2 = couponExample.createCriteria();
        criteria2.andIdIn(couponIds).andStatusEqualTo((short) 0).andDeletedEqualTo(false);

        /*//直接下单没有通过加入购物车，即cartId为0，无法判断这笔订单的金额。
        //显示优惠券这里判断优惠券是否满足最低金额逻辑有点说不通
        if(cartId > 0){
            //2）条件cartId（即id） 查询cart表得price
            //查询该订单的价格
            Cart cart = cartMapper.selectByPrimaryKey(cartId);
            criteria2.andMinLessThan(cart.getPrice());
        }*/

        List<WxCouponMylistCouponVo> couponVos = couponMapper.selectWxCouponSelectlistCouponVoByExample(couponExample);

        return couponVos;
    }

    @Transactional//事务
    @Override
    public int receiveWx(Integer userId, WxCouponReceiveBo receiveBo) {
        int couponId = receiveBo.getCouponId();
        //1） 条件id（coupon_id=45）  查coupon表获得1条coupon数据
        Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
        //2）条件coupon.total、coupon.limit  逻辑判断优惠券是否未领取完，即可以领取？
        if(coupon.getTotal() < 0){
            //这种优惠券已下架/领完，返回：优惠券已领完
            return 740;
        }

        if(coupon.getLimit() == 1){
            //3）条件userId + couponId   查询coupon_user表得到count==0
            //查询该用户是否未领取该种优惠券？
            CouponUserExample couponUserExample = new CouponUserExample();
            CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
            criteria.andUserIdEqualTo(userId).andCouponIdEqualTo(couponId);
            long count = couponUserMapper.countByExample(couponUserExample);
            if(count > 0){
                //该用户已经领取这种优惠券，领取次数已用完，返回：优惠券已领完
                return 740;
            }
        }

        //4）领券过程 添加一条数据到coupon_user表
        // 数据：userId、couponId（请求数据）+ start_time、end_time（ 1）查询结果数据）
        // + add_time、update_time（sql语句or后台生成）
        CouponUser couponUser = new CouponUser();
        couponUser.setUserId(userId);
        couponUser.setCouponId(couponId);
        couponUser.setStartTime(coupon.getStartTime());
        couponUser.setEndTime(coupon.getEndTime());
        Date currentTime = DataUtils.getCurrentTime();
        couponUser.setAddTime(currentTime);
        couponUser.setUpdateTime(currentTime);
        //涉及事务
        couponUserMapper.insertSelective(couponUser);

        //5）条件id（coupon_id）  修改coupon表total
        //根据领券前total值不同，修改成不同的值or不修改
        Coupon couponUpdate = new Coupon();
        couponUpdate.setId(couponId);
        Integer total = coupon.getTotal();
        if(total == 0){
            return 0;//领取成功
        }else if(total == 1){
            //total领取后，修改为-1
            couponUpdate.setTotal(-1);
        }else{
            //total>1，领取后-1
            couponUpdate.setTotal(total - 1);
        }
        couponMapper.updateByPrimaryKeySelective(couponUpdate);
        return 0;//领取成功
    }

    @Transactional//事务
    @Override
    public int exchange(Integer userId, String code) {
        //1）条件code + type=2(优惠券码兑换)  + deleted=false 查询coupon表得到数据coupon
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();
        criteria.andCodeEqualTo(code).andTypeEqualTo((short)2).andDeletedEqualTo(false);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);

        //2）领券前，判断该券是否可领取？
        //coupon.total>0，则可领取。
        if(coupons.size() == 0){
            //不存在此优惠券，响应：优惠券不正确
            return 742;
        }
        //可能有多条，我们这里只取第一条（视兑换码唯一）
        Coupon coupon = coupons.get(0);
        if(coupon.getTotal() < 0){
            //该优惠券已领完，响应：优惠券不正确
            return 742;
        }

        //3）判断该用户是否可领取这种券？
        //条件userId + coupon_id    查询coupon_user得到count==0，则可领取。
        Integer couponId = coupon.getId();
        if(coupon.getLimit() == 1){//限额领取
            CouponUserExample couponUserExample = new CouponUserExample();
            CouponUserExample.Criteria criteriaCouponuser = couponUserExample.createCriteria();
            criteriaCouponuser.andUserIdEqualTo(userId).andCouponIdEqualTo(couponId);
            long count = couponUserMapper.countByExample(couponUserExample);
            if(count > 0){
                //该用户已兑换，响应：优惠券已兑换
                return 740;
            }
        }

        //4）领券
        //添加coupon_user表  数据userId、coupon.id、coupon.start_time、coupon.end_time
        // + 后台生成add_time、update_time
        CouponUser couponUser = new CouponUser();
        couponUser.setUserId(userId);
        couponUser.setCouponId(couponId);
        couponUser.setStartTime(coupon.getStartTime());
        couponUser.setEndTime(coupon.getEndTime());
        Date currentTime = DataUtils.getCurrentTime();
        couponUser.setAddTime(currentTime);
        couponUser.setUpdateTime(currentTime);
        couponUserMapper.insertSelective(couponUser);

        //5）领券后
        //修改coupon表的total-1（分3种情况）
        Coupon couponUpdate = new Coupon();
        couponUpdate.setId(couponId);
        Integer total = coupon.getTotal();
        if(total == 0){
            return 0;//领取成功
        }else if(total == 1){
            //total领取后，修改为-1
            couponUpdate.setTotal(-1);
        }else{
            //total>1，领取后-1
            couponUpdate.setTotal(total - 1);
        }
        couponMapper.updateByPrimaryKeySelective(couponUpdate);
        return 0;//领取成功
    }
}
